package com.ayu.shortlink.engine.util;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.ayu.shortlink.engine.common.enums.CouponRemindTypeEnum;
import com.ayu.shortlink.engine.dto.req.CouponTemplateRemindCreateReqDTO;
import com.ayu.shortlink.engine.dto.resp.CouponTemplateRemindFindAllRespDTO;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 提醒工具类
 */
public class CouponTemplateRemindUtil {
    private static final Integer BIT_SIT = 12;
    private static final Integer TYPE = CouponRemindTypeEnum.values().length;
    /**
     * 5分钟为一个间隔
     */
    private static final Integer TIME_INTERVAL = 5;

    public static Long reverse(Long information, CouponTemplateRemindCreateReqDTO requestParam){
        return information|compute(requestParam.getType(), requestParam.getRemindTime());
    }

    public static Long compute(Integer type,Integer remindTime){
        return 1L<<type*BIT_SIT+Math.max(0,remindTime/TIME_INTERVAL-1);
    }

    /**
     * 检查是否这个时间段已经发送
     * @return true - 已经发送 false - 还没发送
     */
    public static Boolean isSend(Long messageStatus,Integer level){
        return (messageStatus & (1L<<level)) != 0;
    }

    /**
     * 计算下一个消息状态
     * @return 下一个消息状态
     */
    public static Long computeNextMessageStatus(Long messageStatus,Integer level){
        return messageStatus | (1L<<level);
    }

    public static Boolean isReverse(Long information, CouponTemplateRemindCreateReqDTO requestParam){
        return (information&compute(requestParam.getType(), requestParam.getRemindTime())) != 0;
    }

    public static void fillCouponRemindInformation(CouponTemplateRemindFindAllRespDTO respDTO, Long information){
        //开抢时间
        Date validStartTime = respDTO.getValidStartTime();
        //回退一小时 方便去计算提醒时间
        DateTime offsetHour = DateUtil.offsetHour(validStartTime, -1);
        List<Date> dateList = new ArrayList<>();
        List<String> remindType = new ArrayList<>();

        //从后面开始遍历
        for (int i = BIT_SIT-1; i >= 0; i--) {
            for (int j = 0; j < TYPE; j++) {
                if((information&( 1L << j*BIT_SIT + i)) != 0){
                    //填充提醒类型
                    remindType.add(CouponRemindTypeEnum.getDescribeByType(j));
                    //填充提醒时间
                    dateList.add(DateUtil.offsetMinute(offsetHour,(i+1) * TIME_INTERVAL));
                }
            }
        }
        respDTO.setRemindTime(dateList);
        respDTO.setRemindType(remindType);
    }
}
